package com.sites.common.file;

import java.io.File;
import java.io.IOException;

import net.coobird.thumbnailator.Thumbnails;

import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.core.Controller;
import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;
import com.jfinal.log.Log4jLog;
import com.jfinal.upload.UploadFile;
import com.sites.common.SiteInfo;

/**
 * 文件上传下载拦截器
 * 
 * @author zyg 2020年7月27日 下午6:47:43
 */
public class FileInterceptor implements Interceptor {

	private Log4jLog log = Log4jLog.getLog(FileInterceptor.class);

	public void intercept(Invocation inv) {
		Ret ret = Ret.fail();
		Controller controller = inv.getController();
		String methodName = inv.getMethodName();

		// 富文本编辑器的图片上传、文章缩略图上传、图集上传校验：大小限制、格式限制
		if ("uploadThumbnail".equals(methodName)
				|| "uploadImg4Editor".equals(methodName)
				|| "uploadImgs".equals(methodName)) {
			try {
				// 文件限定大小单位是B
				UploadFile uploadFile = controller.getFile("file", "",SiteInfo.imgMaxSize * 1024 * 1024);
				// 获取配置文件中的压缩配置，默认进行压缩
				// boolean scaleImg = PropKit.getBoolean("scaleImg", true);
				// if(scaleImg){
				// scaleImg(uploadFile);
				// }
				// 校验文件后缀名
				String originalName = uploadFile.getOriginalFileName();
				String suffix = originalName.substring(originalName.lastIndexOf(".") + 1);
				if (!isPermit(suffix, SiteInfo.thumbnailSuffix)) {
					ret.set(SiteInfo.msgKey, "不支持该文件格式！");
					controller.renderJson(ret);
					return;
				}
			} catch (RuntimeException e) {// 实测这个能捕获文件超限的异常
				e.printStackTrace();
				log.error("文件上传异常", e);
				ret.setFail();
				ret.set(SiteInfo.msgKey, "文件大小超出限制！");
				controller.renderJson(ret);
				return;
			}
		}

		// 文章附件上传校验：大小限制、格式限制
		if ("uploadAnnex".equals(methodName)) {
			try {
				// 文件限定大小单位是B
				UploadFile uploadFile = controller.getFile("file", "", SiteInfo.fileMaxSize * 1024 * 1024);
				// 校验文件后缀名
				String originalName = uploadFile.getOriginalFileName();
				String suffix = originalName.substring(originalName
						.lastIndexOf(".") + 1);
				if (!isPermit(suffix, SiteInfo.fileSuffix)) {
					ret.set(SiteInfo.msgKey, "不支持该文件格式！");
					controller.renderJson(ret);
					return;
				}
			} catch (RuntimeException e) {// 实测这个能捕获文件超限的异常
				e.printStackTrace();
				log.error("文件上传异常", e);
				ret.setFail();
				ret.set(SiteInfo.msgKey, "文件大小超出限制！");
				controller.renderJson(ret);
				return;
			}
		}
		
		// 富文本上传视频校验：大小限制、格式限制
		if ("uploadVideo4Editor".equals(methodName)) {
			try {
				// 文件限定大小单位是B
				UploadFile uploadFile = controller.getFile("video", "", SiteInfo.videoMaxSize * 1024 * 1024);
				// 校验文件后缀名
				String originalName = uploadFile.getOriginalFileName();
				String suffix = originalName.substring(originalName
						.lastIndexOf(".") + 1);
				if (!isPermit(suffix, SiteInfo.videoSuffix)) {
					ret.set(SiteInfo.msgKey, "不支持该文件格式！");
					controller.renderJson(ret);
					return;
				}
			} catch (RuntimeException e) {// 实测这个能捕获文件超限的异常
				e.printStackTrace();
				log.error("文件上传异常", e);
				ret.setFail();
				ret.set(SiteInfo.msgKey, "文件大小超出限制！");
				controller.renderJson(ret);
				return;
			}
		}

		inv.invoke();

	}

	/**
	 * 判断文件后缀是否在许可范围内
	 * 
	 * @param suffix	文件的后缀
	 * @param allowableSuffix	允许的文件后缀
	 * @return
	 */
	private boolean isPermit(String suffix, String allowableSuffix) {
		if (StrKit.isBlank(suffix) || StrKit.isBlank(allowableSuffix)) {
			return false;
		}

		boolean flag = false;
		String[] permitSuffix = allowableSuffix.split("\\|");// 分割符需要进行转译
		for (int i = 0, j = permitSuffix.length; i < j; i++) {
			if (suffix.equals(permitSuffix[i])) {
				flag = true;
				break;
			}
		}

		return flag;
	}

	/**
	 * 压缩图片
	 * 
	 * @param uploadFile
	 *            上传的文件
	 */
	@SuppressWarnings("unused")
	private void scaleImg(UploadFile uploadFile) {
		// 获取文件类型
		String contentType = uploadFile.getContentType();
		String type = contentType.split("/")[0];
		if (!"image".equalsIgnoreCase(type)) {
			// 不是图片文件时不做处理
			return;
		}
		// 获取上传的文件
		File file = uploadFile.getFile();
		float fileSize = (float) file.length() / 1024 / 1024;// 获取文件大小，以M为单位
		// 进行压缩处理，可以根据不同的大小或类型进行不同层级的处理
		try {
			if (fileSize < 1) {
				return;
			}
			if (fileSize > 5) {
				Thumbnails.of(file).scale(0.4).toFile(file);
			} else if (fileSize > 3) {
				Thumbnails.of(file).scale(0.5).toFile(file);
			} else if (fileSize > 2) {
				Thumbnails.of(file).scale(0.6).toFile(file);
			} else if (fileSize > 1) {
				Thumbnails.of(file).scale(0.8).toFile(file);
			}
		} catch (IOException e) {
			log.error("图片压缩异常：", e);
		}
	}
}
